import hashlib
import socketserver
import json,os
import configparser
from config import settings

STATUS_CODE={'1':"passed authenticate",
             "0":"fail",
             "200":"success",
             "253":"Wrong username or password",
             "254":"passed authenticate ",
             "250":"invalid cmd format,e.g:{'action':'get','filename':'test.py','filesize':'344'}",
             "256":"Filname doesn't exits on server",
             "257":"ready to send file",
             "500":"internet server error",
             "404":"soure not exite",
             "802":"文件不存在",
             "801":"文件已存在",
             '800':"文件存在但不完整"
             }
class ServerHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                data = self.request.recv(1024).strip() # conn=self.request
                data = json.loads(data.decode("utf-8"))
                '''{"action":"auth",
                    "username":"yuan",
                    "pwd":"123"
                    }
                '''
                if data.get("action"):
                    if hasattr(self,data.get("action")):
                        func = getattr(self,data.get("action"))
                        func(**data)
                    else:
                        print("命令错误！")
                else:
                    print("命令为空！")
            except Exception:
                print(Exception)


    def send_data(self,data):

        self.request.sendall(json.dumps(data).encode("utf-8"))

    def auth(self,**data):
        print("客户端发来的消息是：",data)
        username=data.get('username')
        password=data.get("password")

        user = self.authenticate(username,password)

        if user:
            self.send_response(254)
            print('登陆成功')
        else:
            self.send_response(253)
            print("登陆失败")

    def send_response(self,status_code):
        # response = {"status_code":status_code,"status_mes":STATUS_CODE[status_code]}
        response = {"status_code": status_code}
        self.request.sendall(json.dumps(response).encode("utf-8"))


    def authenticate(self,user,pwd):
        cfg = configparser.ConfigParser()
        cfg.read(settings.ACCOUNTS_PATH)
        print(settings.ACCOUNTS_PATH)
        if user in cfg.sections():
            print(cfg.sections())
            print("------------------------")
            if cfg[user]['password'] == pwd:
                print("登陆成功")
                self.user = user
                self.mainPath=os.path.join(settings.BASE_DIR,"home",self.user)
            return user

    def get(self,**kwargs):
        pass

    def ls(self,**data):
        file_list=os.listdir(self.mainPath)
        file_str="\n".join(file_list)
        if not len(file_list):
            file_str="<empty dir>"
        self.request.sendall(json.dumps(file_str).encode("utf-8"))

    # def cd(self,**data):
    #     file_str = "<empty dir>"
    #     # self.request.sendall(json.dumps(file_str).encode("utf-8"))
    #     self.send_data(file_str)

    def cd(self,**data):
        dirname = data.get("dirname")
        if dirname=="..":
            self.mainPath = os.path.dirname(self.mainPath)
        else:
            self.mainPath = os.path.join(self.mainPath,dirname)
        # self.request.sendall(self.mainPath.encode("utf-8"))
        self.send_data(self.mainPath)

    def makedir(self,**data):
        dirname = data.get("dirname")
        path =os.path.join(self.mainPath,dirname)
        if not os.path.exists(path):
            if "/" in dirname:
                os.makedirs(path)
            else:
                os.mkdir(path)
            self.request.sendall("make dir sucess").encode("utf-8")
        else:
            self.request.sendall("dir exits").encode("utf-8")

    def put(self,**data):
        print("date")
        file_name = data.get('file_name')
        file_size = data.get('file_size')
        target_path = data.get("target_path")
        abs_path=os.path.join(self.mainPath,target_path,file_name)
        # ---------------------------------------------------
        has_received=0
        if os.path.exists(abs_path):
            file_has_size = os.stat(abs_path).st_size
            if file_has_size<file_size:
                '''断点续传'''
                self.send_response(800)
                user_choice = self.request.recv(1024).decode("utf-8")
                if user_choice=='Y':
                    self.request.sendall(str(file_has_size)).encode("utf-8")
                    has_received = file_has_size
                    f = open(abs_path,"ab")
                else:
                    f = open(abs_path,"wb")
            else:
                '''文件存在,且完整'''
                self.send_response(801)
                return

        else:
            self.send_response(802)
            f = open(abs_path,"wb")
        md5_obj = hashlib.md5()
        while has_received < file_size:
            try:
                data = self.request.recv(1024)
            except Exception :
                break
            f.write(data)
            md5_obj.update(data)
            has_received +=len(data)
            md5_val =md5_obj.hexdigest()
            respone_md5_val=self.request.recv(1024).decode('utf-8')
            if md5_val==respone_md5_val:
                print("文件传输完整")
            else:
                print("文件传输不完整")
        f.close()


'''python ftp_client.py -s localhost -P 1234 -u alex -p 123123
   python ftp_server.py start
'''


